﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Core.Module.Interfaces;
using Core.Module.Interfaces.Manager;
using Core.Module.Interfaces.Model;
using umbraco.interfaces;
using System.Web;
using umbraco;
using System.Xml;
using System.Collections;
using umbraco.cms.businesslogic;
using umbraco.cms.businesslogic.web;


namespace Core.Module.Manager
{
    public class NodeManager : INodeManager<IFrontend>
    {

        private INode GetFrontendNode(int id,bool getQuickerResult)
        {
            XmlElement _pageXmlNode=(id != -1)? content.Instance.XmlContent.DocumentElement.OwnerDocument.GetElementById(id.ToString())
                :content.Instance.XmlContent.DocumentElement;
            return new umbraco.NodeFactory.Node(_pageXmlNode, getQuickerResult);
        }

        public IModuleNode Get(int nodeid)
        {
            return ToModuleNode(GetFrontendNode(nodeid,true));
        }

        public IModuleNode ToModuleNode(INode node)
        {
            IModuleNode result = ObjectManager.Resolve<IModuleNode>();
            result.Data = node;
            result.Alias = node.NodeTypeAlias;
            result.Name = node.Name;
            result.Id = node.Id.ToString();
            result.Title = GetPropertyValue(result, "title") as string;
            result.Url = node.NiceUrl;
            result.Path = node.Path ?? "";
            result.Parents = result.Path.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
            result.SiteId = result.Parents != null && result.Parents.Length > 0 ? result.Parents[1] : result.Id;            
            return result;
        }


        public IEnumerable<IModuleNode> GetChildren(int parentId)
        {
            INode fNode = GetFrontendNode(parentId, true);
            return fNode.ChildrenAsList.Select(fn => ToModuleNode(fn));
        }




        public IEnumerable<IModuleNode> GetChildren(int parentId, string nodeTypeName)
        {
            INode fNode = GetFrontendNode(parentId, true);
            return fNode.ChildrenAsList
                .Where(fni => fni.NodeTypeAlias.Equals(nodeTypeName,StringComparison.CurrentCultureIgnoreCase))
                .Select(fni => ToModuleNode(fni));
        }



        public IModuleNode GetChild(int parentId, string nodeTypeName)
        {
            INode fNode = GetFrontendNode(parentId, true);
            Int32 nid= fNode.Id;
            INode rNode = fNode.ChildrenAsList
                .Where(fni => fni.NodeTypeAlias.Equals(nodeTypeName, StringComparison.CurrentCultureIgnoreCase))
                .FirstOrDefault();
            return rNode==null?null: ToModuleNode(rNode);
        }
        public IModuleNode GetChild(IModuleNode parentNode, string nodeTypeName)
        {
            INode fNode = parentNode.Data as INode;
            if (fNode ==null) return null;
            INode rNode = fNode.ChildrenAsList
                .Where(fni => fni.NodeTypeAlias.Equals(nodeTypeName, StringComparison.CurrentCultureIgnoreCase))
                .FirstOrDefault();
            return rNode == null ? null : ToModuleNode(rNode);
        }


        public object GetPropertyValue(IModuleNode sourceNode, string sourceProperty)
        {
            INode fNode = sourceNode.Data as INode;

            IProperty prop = fNode.GetProperty(sourceProperty);
            if (prop == null) return null;
            return prop.Value;
        }
        
        public IModuleNode GetPropertyAsNode(IModuleNode node, string propertyName)
        {
            string nodeid = GetPropertyValue(node, propertyName) as string;
            int nid;
            if (string.IsNullOrEmpty(nodeid) || !int.TryParse(nodeid,out nid) ||nid<0) return null;
            return Get(nid);
        }

       public IEnumerable<KeyValuePair<string, string>> GetProperties(IModuleNode node)
        {
            INode data = node.Data as INode;
            if (data == null) return null;
            return data.PropertiesAsList.Select(pr => new KeyValuePair<string, string>(pr.Alias, pr.Value));
        }
    }



    public class NodeManagerBackOffice : INodeManager<IBackOffice>
    {

        
        public IModuleNode Get(int nodeid)
        {
            return ToModuleNode(GetNode(nodeid));
        }

        private Content GetNode(int nodeid)
        {
            Content result = new Content(nodeid);
            return result;
        }

        public IModuleNode ToModuleNode(Content node)
        {
            IModuleNode result = ObjectManager.Resolve<IModuleNode>();
            result.Data = node;
            if (node.ContentType != null)
            {
                result.Alias = node.ContentType.Alias;                
            }
            result.Icon = node.ContentTypeIcon;
            result.Name = node.Text;
            result.Id = node.Id.ToString();
            result.Title = GetPropertyValue(result, "title") as string;
            result.Url = null;
            result.Path = node.Path ?? "";
            result.Parents = result.Path.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
            result.SiteId = result.Parents != null && result.Parents.Length > 1 ? result.Parents[1] : result.Id;
            return result;
        }


        public IEnumerable<IModuleNode> GetChildren(int parentId)
        {
            Content bNode = GetNode(parentId);
            return bNode.Children
                .Select(fn => ToModuleNode(new Content(fn.Id) ));
        }

        public IEnumerable<IModuleNode> GetChildren(int parentId, string nodeTypeName)
        {
            Content bNode = GetNode(parentId);
            return bNode.Children.Select(c=>new Content(c.Id))
                .Where(fni => fni.ContentType.Alias.Equals(nodeTypeName, StringComparison.CurrentCultureIgnoreCase))
                .Select(fni => ToModuleNode(fni));
        }



        public IModuleNode GetChild(int parentId, string nodeTypeName)
        {
            Content bNode = GetNode(parentId);
            Int32 nid = bNode.Id;
            Content rNode = bNode.Children.Select(c=>new Content(c.Id))
                .Where(fni => fni.ContentType.Alias.Equals(nodeTypeName, StringComparison.CurrentCultureIgnoreCase))
                .FirstOrDefault();
            return rNode == null ? null : ToModuleNode(rNode);
        }
        public IModuleNode GetChild(IModuleNode parentNode, string nodeTypeName)
        {
            Content bNode = parentNode.Data as Content;
            
            if (bNode == null) return null;
            Content rNode = bNode.Children.Select(c => new Content(c.Id))
                .Where(fni => fni.ContentType.Alias.Equals(nodeTypeName, StringComparison.CurrentCultureIgnoreCase))
                .FirstOrDefault();
            return rNode == null ? null : ToModuleNode(rNode);
        }


        public object GetPropertyValue(IModuleNode sourceNode, string sourceProperty)
        {
            Content fNode = sourceNode.Data as Content;
             
            umbraco.cms.businesslogic.property.Property prop = fNode.getProperty(sourceProperty);
            if (prop == null) return null;
            return prop.Value;
        }

        public IModuleNode GetPropertyAsNode(IModuleNode node, string propertyName)
        {
            string nodeid = GetPropertyValue(node, propertyName) as string;
            int nid;
            if (string.IsNullOrEmpty(nodeid) || !int.TryParse(nodeid, out nid) || nid < 0) return null;
            return Get(nid);
        }

        public IEnumerable<KeyValuePair<string, string>> GetProperties(IModuleNode node)
        {
            INode data = node.Data as INode;
            if (data == null) return null;
            return data.PropertiesAsList.Select(pr => new KeyValuePair<string, string>(pr.Alias, pr.Value));
        }
    }
}
